package com.copro.chemdb.result;

import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.ihelpuoo.lang.NumericUtils;

import com.copro.chemdb.constants.ConstValue;
import com.copro.chemdb.constants.ConstValueUtils;
import com.copro.chemdb.ques.QuesUtils;
import com.copro.chemdb.ques.Questionnaire;
import com.copro.chemdb.subject.Subject;
import com.copro.chemdb.subject.SubjectUtils;
import com.copro.chemdb.subject.opt.Option;
import com.copro.simple.Application;
import com.copro.simple.SimpleException;
import com.copro.simple.SimpleSession;
import com.copro.simple.SimpleUtils;

public class SaveResultAction extends Action {

	@Override
	public ActionForward execute(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		Result result = (Result) form;
		int saveType = NumericUtils.parseInt(request.getParameter("type"), 0);
		Application app = Application.me(request);
		List<Subject> subjects = SubjectUtils.queryAllSubjects(app, result
				.getQuesId());
		if (subjects.size() == 0)
			return mapping.findForward("edit");

		loadFromHttpRequest(app, request, result, subjects);
		result.setUser(SimpleSession.me((HttpServletRequest) request)
				.getAccount().getName());
		if (result.getId() > 0) {
			Result dbre = ResultUtils.getResult(app, result.getId());
			if (dbre.getId() > 0)
				result.setType(dbre.getType());
			else
				result.setId(0);
		}
		/* check the result kep field, it should not be NULL */
		boolean hasKeyAnswer = checkResult(result, app);
		if (!hasKeyAnswer) {
			response.getWriter().print("REJECT");
			return null;
		}

		ResultUtils.saveToDatabase(app, result, saveType);

		return mapping.findForward("save-ok");
	}

	private boolean checkResult(Result result, Application app)
			throws SimpleException {
		Questionnaire ques = QuesUtils.getById(app, result.getQuesId());
		Iterator<Answer> it = result.getAnswers().iterator();
		boolean hasKeyAnswer = false;
		while (it.hasNext()) {
			Answer an = it.next();
			if (an.getSubjectId() == ques.getKeySubjectId()) {
				hasKeyAnswer = !an.isBlank();
				break;
			}
		}
		return hasKeyAnswer;
	}

	private Result loadFromHttpRequest(Application app,
			HttpServletRequest request, Result result, List<Subject> subjects)
			throws SimpleException {
		Iterator<Subject> it = subjects.iterator();
		StringBuffer name;
		while (it.hasNext()) {
			Subject subject = it.next();
			if (!result.isIncluded(subject))
				continue;
			int sid = subject.getId();
			Answer an = new Answer();
			an.setSubjectId(sid);
			/* Default */
			if (subject.isDefault()) {
				continue;

			} else if (subject.isEnum()) {
				name = new StringBuffer("s.").append(sid).append(".num");
				int intValue = NumericUtils.parseInt(request.getParameter(name
						.toString()), -1);
				an.setIntValue(intValue);
				ConstValue v = ConstValueUtils.getConstValue(app, subject
						.getEnumType(), intValue);
				an.setText(v.getName());
				if (!an.isBlank())
					result.getAnswers().add(an);

			} else if (subject.isText()) {
				name = new StringBuffer("s.").append(sid).append(".str");
				an.setStrValue(request.getParameter(name.toString()));
				an.setText(an.getStrValue());
				int vint = NumericUtils.parseInt(an.getStrValue(), -1);
				if (vint >= 0)
					an.setIntValue(vint);
				if (!an.isBlank())
					result.getAnswers().add(an);

			} else if (subject.isMultiSelect()) {
				name = new StringBuffer("s.").append(sid).append(".num");
				String v = request.getParameter(name.toString());
				if (null == v)
					continue;
				String[] ints = SimpleUtils.split(v);

				name = new StringBuffer("s.").append(sid).append(".str");
				v = request.getParameter(name.toString());
				String[] strs = SimpleUtils.split(v);

				for (int i = 0; i < ints.length; i++) {
					Answer an2 = new Answer();
					an2.setSubjectId(sid);
					an2.setIntValue(NumericUtils.parseInt(ints[i], -1));
					an2.setStrValue(strs[i]);
					if (!an2.isBlank()) {
						Option op = SubjectUtils.getOption(app,
								subject.getId(), an2.getIntValue());
						if (op.getId() >= 0)
							an2.setText(op.getText());
						result.getAnswers().add(an2);
					}
				}

			} else if (subject.isSingleSelect()) { // single select!
				name = new StringBuffer("s.").append(sid).append(".str");
				an.setStrValue(request.getParameter(name.toString()));
				name = new StringBuffer("s.").append(sid).append(".num");
				an.setIntValue(NumericUtils.parseInt(request.getParameter(name
						.toString()), -1));
				if (!an.isBlank()) {
					Option op = SubjectUtils.getOption(app, subject.getId(), an
							.getIntValue());
					if (op.getId() >= 0)
						an.setText(op.getText());
					result.getAnswers().add(an);
				}
			} else {
				throw new SimpleException("Subject [" + subject.getId()
						+ "] type can not be " + subject.getType());
			}
		}
		return result;
	}

}
